Skip to content

[iOS] Refactor Touchable not to rely on GestureDetector#4343

Open
j-piasecki wants to merge 6 commits into
mainfrom
touchable-refactor-ios
Open

[iOS] Refactor Touchable not to rely on GestureDetector#4343
j-piasecki wants to merge 6 commits into
mainfrom
touchable-refactor-ios

Conversation

@j-piasecki

Copy link
Copy Markdown
Member

Description

  • RNGestureHandler gains overridable dispatchStateChange/dispatchHandlerUpdate hooks. RNNativeViewGestureHandler forwards them to its bound view through the new RNGHNativeViewHandlerStateObserver protocol (it now keeps a _boundView reference, since for UIControl-based views the recognizer is never attached and recognizer.view can't be used).
  • RNGestureHandlerButton implements the same press state machine as Android, including the native long-press timer.
  • RNGestureHandlerButtonComponentView creates/updates/drops the managed NativeViewGestureHandler (attached with the new RNGestureHandlerActionTypeNone, so nothing is sent to JS) and emits the press events through the codegen event emitter. On iOS the handler manager can't be resolved from the view's context, so a new moduleId prop is used to look it up (no-op on Android).
  • The events are namespaced as onButtonPress etc., because the base iOS view config already registers topPress as a bubbling event — a direct event with the same top-level name fails view-config validation in dev.
  • Touchable.android.tsx is replaced by a shared Touchable.tsx used on all native platforms; the previous JS gesture-driven implementation moves to Touchable.web.tsx (removed in the next PR).
  • Jest tests updated to fire button events instead of gesture-state sequences, matching what the native side now dispatches.

Test plan

Existing tests in the Example app

@j-piasecki
j-piasecki force-pushed the touchable-refactor branch from c233824 to 496a9c1 Compare July 27, 2026 05:59
@j-piasecki
j-piasecki force-pushed the touchable-refactor-ios branch from 1e89ff8 to 4355487 Compare July 27, 2026 06:00
Base automatically changed from touchable-refactor to main July 27, 2026 06:23
@j-piasecki
j-piasecki force-pushed the touchable-refactor-ios branch from 4355487 to 233649d Compare July 27, 2026 06:24
Copilot AI review requested due to automatic review settings July 27, 2026 06:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors v3 Touchable on iOS to stop relying on GestureDetector and instead drive press interactions via a managed NativeViewGestureHandler + native button state machine, aligning iOS behavior more closely with Android and simplifying JS-side logic.

Changes:

  • Introduces native-side observer hooks (dispatchStateChange / dispatchHandlerUpdate) so RNNativeViewGestureHandler can forward state/update information to the bound view (needed for UIControl cases).
  • Namespaces button press events (onButtonPress*) and updates JS components/tests to consume button events rather than gesture state sequences.
  • Splits Touchable implementation: shared native (Touchable.tsx) uses button events; web (Touchable.web.tsx) keeps the JS gesture-driven implementation; removes Touchable.android.tsx.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/react-native-gesture-handler/src/v3/components/Touchable/TouchableProps.ts Updates omitted native button event prop names to onButton* so Touchable can own the mapping.
packages/react-native-gesture-handler/src/v3/components/Touchable/Touchable.web.tsx Adds web-specific implementation retaining JS gesture-driven press behavior.
packages/react-native-gesture-handler/src/v3/components/Touchable/Touchable.tsx Switches native platforms to use GestureHandlerButton’s namespaced button events + managed handler props.
packages/react-native-gesture-handler/src/v3/components/Touchable/Touchable.android.tsx Removes Android-only implementation in favor of shared native Touchable.tsx.
packages/react-native-gesture-handler/src/v3/components/GestureButtonsProps.ts Updates omitted native event prop names to onButton*.
packages/react-native-gesture-handler/src/specs/RNGestureHandlerButtonNativeComponent.ts Renames native event props to onButton* and adds moduleId prop (iOS-only usage).
packages/react-native-gesture-handler/src/components/GestureHandlerButton.tsx Updates public TS types to namespaced button events and adds moduleId.
packages/react-native-gesture-handler/src/tests/mocks.test.tsx Updates tests to fire button events (buttonPress) instead of gesture state changes.
packages/react-native-gesture-handler/src/tests/api_v3.test.tsx Updates v3 component tests to simulate native button event sequences (including cancel / long-press).
packages/react-native-gesture-handler/apple/RNGestureHandlerManager.mm Adds support for RNGestureHandlerActionTypeNone (consume natively, don’t dispatch to JS).
packages/react-native-gesture-handler/apple/RNGestureHandlerButtonComponentView.mm Creates/updates/drops a managed NativeViewGestureHandler and dispatches onButton* events via Fabric emitter.
packages/react-native-gesture-handler/apple/RNGestureHandlerButton.mm Implements native press state machine + native long-press timer driven by managed handler state/updates.
packages/react-native-gesture-handler/apple/RNGestureHandlerButton.h Adds button event delegate protocol + managed handler tracking properties.
packages/react-native-gesture-handler/apple/RNGestureHandlerActionType.h Adds RNGestureHandlerActionTypeNone.
packages/react-native-gesture-handler/apple/RNGestureHandler.mm Adds overridable dispatchStateChange / dispatchHandlerUpdate hooks after event dispatch.
packages/react-native-gesture-handler/apple/RNGestureHandler.h Declares the new overridable dispatch hooks.
packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm Tracks bound view for UIControl scenarios and forwards handler updates/state changes to observer protocol.
packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.h Adds RNGHNativeViewHandlerStateObserver protocol for bound views to observe updates/state changes.
packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt Adds no-op moduleId prop setter on Android (iOS-only behavior).
packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/events/RNGestureHandlerButtonEvent.kt Renames Android button event names to onButton* for cross-platform consistency.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/react-native-gesture-handler/apple/Handlers/RNNativeViewHandler.mm Outdated
@j-piasecki
j-piasecki force-pushed the touchable-refactor-ios branch from 233649d to 71d694d Compare July 27, 2026 07:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants